home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Games Extra 1996 September
/
Amiga Games Extra CD-ROM 9-1996.iso
/
userbox
/
publicdomain
/
vim-4.2
/
src
/
alloc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-09
|
7KB
|
382 lines
/* vi:set ts=4 sw=4:
*
* VIM - Vi IMproved by Bram Moolenaar
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
*/
/*
* alloc.c
*
* This file contains various routines dealing with allocation and
* deallocation of memory. And some funcions for copying text.
*/
#include "vim.h"
#include "globals.h"
#include "proto.h"
/*
* Some memory is reserved for error messages and for being able to
* call mf_release_all(), which needs some memory for mf_trans_add().
*/
#define KEEP_ROOM 8192L
/*
* Note: if unsinged is 16 bits we can only allocate up to 64K with alloc().
* Use lalloc for larger blocks.
*/
char_u *
alloc(size)
unsigned size;
{
return (lalloc((long_u)size, TRUE));
}
/*
* alloc() with check for maximum line length
*/
char_u *
alloc_check(size)
unsigned size;
{
#if !defined(UNIX) && !defined(__EMX__)
if (sizeof(int) == 2 && size > 0x7fff)
{
EMSG("Line is becoming too long");
return NULL;
}
#endif
return (lalloc((long_u)size, TRUE));
}
char_u *
lalloc(size, message)
long_u size;
int message;
{
register char_u *p; /* pointer to new storage space */
static int releasing = FALSE; /* don't do mf_release_all() recursive */
int try_again;
if (size <= 0)
{
EMSGN("Internal error: lalloc(%ld, )", size);
return NULL;
}
#if defined(MSDOS) && !defined(DJGPP)
if (size >= 0xfff0) /* in MSDOS we can't deal with >64K blocks */
p = NULL;
else
#endif
/*
* If out of memory, try to release some memfile blocks.
* If some blocks are released call malloc again.
*/
for (;;)
{
if ((p = (char_u *)malloc(size)) != NULL)
{
if (mch_avail_mem(TRUE) < KEEP_ROOM && !releasing)
{ /* System is low... no go! */
vim_free((char *)p);
p = NULL;
}
}
/*
* Remember that mf_release_all() is being called to avoid an endless loop,
* because mf_release_all() may call alloc() recursively.
*/
if (p != NULL || releasing)
break;
releasing = TRUE;
try_again = mf_release_all();
releasing = FALSE;
if (!try_again)
break;
}
/*
* Avoid repeating the error message many times (they take 1 second each).
* Did_outofmem_msg is reset when a character is read.
*/
if (message && p == NULL)
do_outofmem_msg();
return (p);
}
void
do_outofmem_msg()
{
if (!did_outofmem_msg)
{
emsg(e_outofmem);
did_outofmem_msg = TRUE;
}
}
/*
* copy a string into newly allocated memory
*/
char_u *
strsave(string)
char_u *string;
{
char_u *p;
p = alloc((unsigned) (STRLEN(string) + 1));
if (p != NULL)
STRCPY(p, string);
return p;
}
char_u *
strnsave(string, len)
char_u *string;
int len;
{
char_u *p;
p = alloc((unsigned) (len + 1));
if (p != NULL)
{
STRNCPY(p, string, len);
p[len] = NUL;
}
return p;
}
/*
* Same as strsave(), but any characters found in esc_chars are preceded by a
* backslash.
*/
char_u *
strsave_escaped(string, esc_chars)
char_u *string;
char_u *esc_chars;
{
char_u *p;
char_u *p2;
char_u *escaped_string;
unsigned length;
/*
* First count the number of backslashes required.
* Then allocate the memory and insert them.
*/
length = 1; /* count the trailing '/' and NUL */
for (p = string; *p; p++)
{
if (vim_strchr(esc_chars, *p) != NULL)
++length; /* count a backslash */
++length; /* count an ordinary char */
}
escaped_string = alloc(length);
if (escaped_string != NULL)
{
p2 = escaped_string;
for (p = string; *p; p++)
{
if (vim_strchr(esc_chars, *p) != NULL)
*p2++ = '\\';
*p2++ = *p;
}
*p2 = NUL;
}
return escaped_string;
}
/*
* copy a number of spaces
*/
void
copy_spaces(ptr, count)
char_u *ptr;
size_t count;
{
register size_t i = count;
register char_u *p = ptr;
while (i--)
*p++ = ' ';
}
/*
* delete spaces at the end of a string
*/
void
del_trailing_spaces(ptr)
char_u *ptr;
{
char_u *q;
q = ptr + STRLEN(ptr);
while (--q > ptr && vim_iswhite(q[0]) && q[-1] != '\\' &&
q[-1] != Ctrl('V'))
*q = NUL;
}
/*
* Isolate one part of a string option where parts are separated with commas.
* The part is copied into buf[maxlen].
* "*option" is advanced to the next part.
* The length is returned.
*/
int
copy_option_part(option, buf, maxlen, sep_chars)
char_u **option;
char_u *buf;
int maxlen;
char *sep_chars;
{
int len = 0;
char_u *p = *option;
/* skip '.' at start of option part, for 'suffixes' */
if (*p == '.')
buf[len++] = *p++;
while (*p && vim_strchr((char_u *)sep_chars, *p) == NULL)
{
/*
* Skip backslash before a separator character and space.
*/
if (p[0] == '\\' && vim_strchr((char_u *)sep_chars, p[1]) != NULL)
++p;
if (len < maxlen - 1)
buf[len++] = *p;
++p;
}
buf[len] = NUL;
p = skip_to_option_part(p); /* p points to next file name */
*option = p;
return len;
}
/*
* replacement for free() that ignores NULL pointers
*/
void
vim_free(x)
void *x;
{
if (x != NULL)
free(x);
}
#ifndef HAVE_MEMSET
void *
vim_memset(ptr, c, size)
void *ptr;
int c;
size_t size;
{
register char *p = ptr;
while (size-- > 0)
*p++ = c;
return ptr;
}
#endif
#ifdef VIM_MEMMOVE
/*
* Version of memmove that handles overlapping source and destination.
* For systems that don't have a function that is guaranteed to do that (SYSV).
*/
void
vim_memmove(dst_arg, src_arg, len)
void *src_arg, *dst_arg;
size_t len;
{
/*
* A void doesn't have a size, we use char pointers.
*/
register char *dst = dst_arg, *src = src_arg;
/* overlap, copy backwards */
if (dst > src && dst < src + len)
{
src +=len;
dst +=len;
while (len-- > 0)
*--dst = *--src;
}
else /* copy forwards */
while (len-- > 0)
*dst++ = *src++;
}
#endif
/*
* compare two strings, ignoring case
* return 0 for match, 1 for difference
*/
int
vim_strnicmp(s1, s2, len)
char_u *s1;
char_u *s2;
size_t len;
{
while (len)
{
if (TO_UPPER(*s1) != TO_UPPER(*s2))
return 1; /* this character different */
if (*s1 == NUL)
return 0; /* strings match until NUL */
++s1;
++s2;
--len;
}
return 0; /* strings match */
}
/*
* Version of strchr() and strrchr() that handle unsigned char strings
* with characters above 128 correctly. Also it doesn't return a pointer to
* the NUL at the end of the string.
*/
char_u *
vim_strchr(string, n)
char_u *string;
int n;
{
while (*string)
{
if (*string == n)
return string;
++string;
}
return NULL;
}
char_u *
vim_strrchr(string, n)
char_u *string;
int n;
{
char_u *retval = NULL;
while (*string)
{
if (*string == n)
retval = string;
++string;
}
return retval;
}
/*
* Vim has its own isspace() function, because on some machines isspace()
* can't handle characters above 128.
*/
int
vim_isspace(x)
int x;
{
return ((x >= 9 && x <= 13) || x == ' ');
}